package com.etc.service.arithmetic;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 
 * 构建矩阵,调用百度地图API算两个景点间的最短乘车路线
 * 试用于一个城市内的4-6个景点间的路线规划
 * @author 小吴
 *
 */
public class BuildMatrix {

	 /*public static void main(String[] args) {
		List<ScenicMessage> list = new ArrayList<>();
		ScenicMessage s1 = new ScenicMessage(0,"蔡塘广场",24.48923061,118.16388605,4);
		ScenicMessage s2 = new ScenicMessage(1,"人才中心",24.48923061,118.10388605,2);
		ScenicMessage s3 = new ScenicMessage(2,"兴源社区",24.51923061,118.13388605,3);
		ScenicMessage s4 = new ScenicMessage(3,"南普陀",24.44923061,118.10388605,4);
		ScenicMessage s5 = new ScenicMessage(4,"何厝边防",24.48923061,118.20388605,4);
		list.add(s1);
		list.add(s2);
		list.add(s3);
		list.add(s4);
		list.add(s5);
		planWay(list);
	}*/
	
	//获取所有景点的路线,并返回一条最佳路线
	public static List<TakeCatWay> planWay(List<ScenicMessage> list) {
		List<TakeCatWay> listTCW =  new ArrayList<>();
		//每个景点进行组合
		for(int i = 0 ; i < list.size();i++) {
			for(int j = 0 ; j < list.size();j++) {				
				if(i==j) {
					TakeCatWay tcw = new TakeCatWay(null, null, 0, 0, 0, 0, 0, 0, null, 0);
					listTCW.add(tcw);
				}else {
					TakeCatWay tcw = new TakeCatWay();
					tcw.setStar(list.get(i).getsName());
					tcw.setStarX(list.get(i).getsX());
					tcw.setStarY(list.get(i).getsY());
					tcw.setEnd(list.get(j).getsName());
					tcw.setEndX(list.get(j).getsX());
					tcw.setEndY(list.get(j).getsY());
					tcw.setTime(list.get(i).getTime());
					//两景点之间的公交路线
					listTCW.add(getTwoPointsBetweenPoth(tcw));					
				}
			}
		}
		
		List<Double> timelist = new ArrayList<>();
		for(int i = 0 ; i < listTCW.size(); i++) {
			double d = listTCW.get(i).getDuration()+listTCW.get(i).getTime();
			
			timelist.add(d);
		}
		
 		double[][] matrix =buildmatrix(list.size(),timelist);//创建二维数组
 		
 		TSP tsp = new TSP(matrix);
 		System.out.println("城市顺序：" + tsp.getFirnalCityFlow());
 		String wayStr =  tsp.getFirnalCityFlow();
 		String way = wayStr.replace("->", "");
 		//System.out.println("way:"+way);
 		//最佳路线图
 		List<TakeCatWay> takeWay = new ArrayList<>();
 		
 		for(int i = 1; i < way.length();i++) {
 			int starNo = Integer.parseInt(way.charAt(i-1)+"");
 			int endNo = Integer.parseInt(way.charAt(i)+"");
 			String strName = list.get(starNo).getsName();
 			String endName = list.get(endNo).getsName();
 			for(int j = 0 ; j < listTCW.size();j++) {
 				if(listTCW.get(j).getStar()==null||listTCW.get(j).getEnd()==null) {
 					continue;
 				}else if(listTCW.get(j).getStar().equals(strName)&&listTCW.get(j).getEnd().equals(endName)) {
 					takeWay.add(listTCW.get(j));
 				}
 			}			
 		}
 		
 		//打印旅行路线
 		for(int i = 0 ; i < takeWay.size();i++) {
 			System.out.print(takeWay.get(i).getStar()+"->");
 		}
 		return takeWay;
	}
		
	/**
	 * 创建二维数组
	 * @param length	二维数组的长度
	 * @param timelist		二维数组数据
	 * @return			生成的二维数组
	 */
	public static double[][] buildmatrix(int length,List<Double> timelist){
		double [][] matrix = new double[length][length];
		int count = 0 ;
		for(int i = 0; i < length;i++) {
			for(int j = 0 ; j < length;j++) {
				matrix[i][j] = timelist.get(count);
				count++;
			}
		}
		return matrix;
	}

	/**
	 * 返回两景点之间的公交路线
	 * @param tcw 两景点的基本信息
	 * @return
	 */
	public static TakeCatWay getTwoPointsBetweenPoth(TakeCatWay tcw) {
		String url ="http://api.map.baidu.com/direction/v2/transit?origin="+tcw.getStarX()+","+tcw.getStarY()+"&destination="+tcw.getEndX()+","+tcw.getEndY()+"&tactics_incity=3&tactics_intercity=0&page_size=1&ak=jE58U0IbCNrx2LHDg4XgNwNNnsigpg96";
		String s = getResponse(url); //用JAVA发起http请求，并返回json格式的结果
		if(s!=null) {			
			return analysisJson(s,tcw);//解析百度API返回的Json格式
		}else {//没有公交路线
			tcw.setDistance(Integer.MAX_VALUE);
			tcw.setDuration(Integer.MAX_VALUE);
		}
		
		return tcw;
	}

	 //用JAVA发起http请求，并返回json格式的结果
	public static String getResponse(String serverUrl){
       
        StringBuffer result = new StringBuffer();
        try {
            URL url = new URL(serverUrl);
            URLConnection conn = url.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));

            String line;
            while((line = in.readLine()) != null){
                result.append(line);
            }
            in.close();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result.toString();
    }
	
	//解析Json格式
	public static TakeCatWay analysisJson(String json,TakeCatWay tcw) {		
		String reg1="(\"path\":\")[\\d\\.,;]*(\",)";//去路径坐标
		String reg2 ="(,\"vehicle_info\":)[\\{\\w\\s\":\\d,\\u4e00-\\u9fa5]*(\\}\\})";//去公交站详细信息
		String reg3 = "(,\"traffic_condition\":|,\"start_location\":|,\"end_location\":)[\\s\\{,\":\\d.latng\\{\\[]*(\\]|\\})";//去掉起始终点的位置坐标
		String reg4 = "(,\"origin\")[:\\{\\}\\[\\]\\d\\.\",\\w\\u4e00-\\u9fa5;；，。\\(\\)-]*";//去打的的信息
		String reg5 = "(,\"arrive_time\")[:\\s\"\\d-,\\w\\{\\[\\}]*\\]";//去票价信息
		String reg6 ="(\\]\\]\\})";//匹配]]}
		String reg7 = "(\\{\"distance\":)[:\\d,\\w\"\\{\\[\\}\\].\\(\\)\\u4e00-\\u9fa5]*�";//把每种方案分离出来
		String reg8 ="[\\u4e00-\\u9fa5]{1}[\\u4e00-\\u9fa5\\(\\)\\d.]*";//提取乘坐路线
		String reg9 ="(^\\{\"distance\":|\"duration\":)[\\d]*";//提取时长与距离
		String json1 = json.replaceAll(reg1, "");
		String json2 = json1.replaceAll(reg2, "");
		String json3 = json2.replaceAll(reg3, "");
		String json4 = json3.replaceAll(reg4, "");
		String json5 = json4.replaceAll(reg5, "");
		String json6 = json5.replaceAll(reg6, "�");
		String project=null;//保留第一种方案
		Pattern p1 = Pattern.compile(reg7);
		Matcher m1 = p1.matcher(json6);
		while(m1.find()) {
			project =m1.group();
			break;
		}
		//System.out.println(project);
		String way="";//路线
		Pattern p2 = Pattern.compile(reg8);
		if(project!=null) {
			Matcher m2 = p2.matcher(project);
			
			while(m2.find()) {
				if(!way.equals("")) {
					way +="->";
				}
				way =way+m2.group();		
			}	
		}
		
		String reg10 = "[\\D]*";
		String duration="";//时长
		String distance="";//距离
		Pattern p3 = Pattern.compile(reg9);
		if(project!=null) {
			
		
		Matcher m3 = p3.matcher(project);
		for(int i = 0 ;m3.find();i++ ) {
			if(i==0) {
				
				distance =m3.group().replaceAll(reg10,"");
			}else if(i==1) {
				duration=m3.group().replaceAll(reg10,"");
			}				
		}
		}
		double time=Integer.MAX_VALUE;//时长
		int extent=Integer.MAX_VALUE;//长度
		if(!duration.equals("")) {
			time = Double.parseDouble(duration)/3600;
		}
		if(!distance.equals("")) {
			extent = Integer.parseInt(distance);
		}
		if(project==null) {
			way="两景点相距较近，建议步行。";
		}
		tcw.setWay(way);
		tcw.setDistance(extent);
		tcw.setDuration(time);
//		System.out.println(tcw.getStar()+"->"+tcw.getEnd()+"::"+way);
//		System.out.println("duration:"+time+"distance:"+extent);
//		System.out.println("****************************");
		return tcw;
	}
}
